package com.company.management.service.report;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.company.management.controller.report.vo.*;
import com.company.management.domain.reward.ScoreLevel;
import com.company.management.domain.reward.ScoreLog;
import com.company.management.dto.UserDto;
import com.company.management.exception.MessageException;
import com.company.management.mapper.TReportCommentMapper;
import com.company.management.mapper.TReportMapper;
import com.company.management.mapper.TReportShareUsersMapper;
import com.company.management.mapper.UserMapper;
import com.company.management.mapper.reward.ScoreLevelMapper;
import com.company.management.mapper.reward.ScoreLogMapper;
import com.company.management.modal.entity.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ReportServices {
    @Resource
    private TReportMapper tReportMapper;
    @Resource
    private TReportShareUsersMapper shareUsersMapper;
    @Resource
    private TReportCommentMapper reportCommentMapper;
    @Resource
    private TReportShareUsersMapper reportShareUsersMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private ScoreLevelMapper scoreLevelMapper;
    @Resource
    private ScoreLogMapper scoreLogMapper;

    public Long createReport(ReportContextReqVO reqVO) {
        if (reqVO.getShareId() == null) {
            throw new MessageException("汇报人不能为空!");
        }
        if (reqVO.getWorkNote() == null) {
            throw new MessageException("工作内容不能为空!");
        }
        reqVO.getWorkNote().setText(reqVO.getWorkNote().getText().replaceAll("[\r\n]+", ""));
        if (reqVO.getPlanNote() != null) {
            reqVO.getPlanNote().setText(reqVO.getPlanNote().getText().replaceAll("[\r\n]+", ""));
        }
        if (reqVO.getOtherText() != null) {
            reqVO.getOtherText().setText(reqVO.getOtherText().getText().replaceAll("[\r\n]+", ""));
        }
        TReport tReport = new TReport();
        tReport.setReportTime(reqVO.getReportDate());
        tReport.setReportContext(JSONUtil.toJsonStr(reqVO.getWorkNote()));
        tReport.setWorkPlan(reqVO.getPlanNote() == null ? null : JSONUtil.toJsonStr(reqVO.getPlanNote()));
        tReport.setOtherNote(reqVO.getOtherText() == null ? null : JSONUtil.toJsonStr(reqVO.getOtherText()));
        tReport.setAttachmentFileName(reqVO.getAttachmentFileName());
        tReport.setCreateDateTime(LocalDateTime.now());
        tReport.setAttachmentPath(reqVO.getAttachmentPath());
        tReport.setReportType(reqVO.getReportType());
        tReport.setUserId(reqVO.getUserId());
        String[] split = reqVO.getShareId().split(",");
        tReportMapper.insert(tReport);
        if (split.length == 0) {
            throw new MessageException("汇报id不能为空!");
        }
        TReportShareUsers shareUsers = new TReportShareUsers();
        for (String shareId : split) {
            shareUsers.setUserId(Long.valueOf(shareId));
            shareUsers.setReportId(tReport.getReportId());
            shareUsersMapper.insert(shareUsers);
        }
        log.info(reqVO.toString());
        return tReport.getReportId();
    }

    public List<UserReportRespVO> getReportByUserId(ReportContextReqVO reqVO) {
        if (reqVO.getUserId() == null ||
                reqVO.getReportType() == null ||
                reqVO.getReceive() == null) {
            throw new MessageException("无效参数!");
        }
        LocalDateTime startOfDay;
        LocalDateTime endOfDay;
        if (StrUtil.isEmpty(reqVO.getReportDate())) {
            LocalDate today = LocalDate.now();
            startOfDay = today.atStartOfDay();
            endOfDay = today.plusWeeks(1).atStartOfDay();
        } else {
            startOfDay = DateUtil.parseLocalDateTime(reqVO.getReportDate().split(",")[0].trim(), DatePattern.NORM_DATE_PATTERN);
            endOfDay = DateUtil.parseLocalDateTime(reqVO.getReportDate().split(",")[1].trim(), DatePattern.NORM_DATE_PATTERN).plusDays(1);
        }
        List<UserReportRespVO> respVos;
        if (reqVO.getReceive() == 1) {
            //获取共享表中我的userid的数据
            LambdaQueryWrapper<TReportShareUsers> wrapper1 = new LambdaQueryWrapper<TReportShareUsers>()
                    .eq(TReportShareUsers::getUserId, reqVO.getUserId());
            List<TReportShareUsers> shareUsers = reportShareUsersMapper.selectList(wrapper1);
            if (shareUsers.isEmpty()) {
                return Collections.emptyList();
            }
            List<Long> reportIdList = shareUsers.stream().map(TReportShareUsers::getReportId).distinct().collect(Collectors.toList());
            respVos = tReportMapper.selectReportByReceive(startOfDay, endOfDay, reqVO.getReportType(), reportIdList, reqVO.getUserId());
        } else {
            respVos = tReportMapper.selectReportByUserId(startOfDay, endOfDay, reqVO.getReportType(), reqVO.getUserId());
        }
        for (UserReportRespVO item : respVos) {
            item.setWorkContext(JSONUtil.toBean(item.getReportContext(), RichTextVO.class));
            item.setPlanContext(JSONUtil.toBean(item.getWorkPlan(), RichTextVO.class));
            item.setOtherContext(JSONUtil.toBean(item.getOtherNote(), RichTextVO.class));
            List<TReportShareUsers> shareUsers = reportShareUsersMapper.selectList(new LambdaQueryWrapper<TReportShareUsers>()
                    .eq(TReportShareUsers::getReportId, item.getReportId()));
            List<Long> userIdList = shareUsers.stream().map(TReportShareUsers::getUserId).distinct().collect(Collectors.toList());
            if (userIdList.isEmpty()) {
                continue;
            }
            List<User> shareUserList = userMapper.selectList(new LambdaQueryWrapper<User>().in(User::getUserId, userIdList));
            String shareUserName = shareUserList.stream().map(User::getUserName).distinct().collect(Collectors.joining(","));
            item.setShareUserName(shareUserName);
        }
        return respVos;
    }

    /**
     * 创建成功后前端需要重新更新这条报告的评论
     *
     * @param reqVO
     * @return
     */
    public List<UserReportCommentRespVO> createReportComment(ReportCommentReqVO reqVO) {
        TReportComment reportComment = new TReportComment()
                .setReportId(reqVO.getReportId())
                .setUserId(reqVO.getUserId())
                .setContext(reqVO.getCommentContent())
                .setCreateDateTime(LocalDateTime.now());

        int insert = reportCommentMapper.insert(reportComment);
        if (insert == 0) {
            throw new MessageException("保存失败!");
        }
        return getReportComment(reqVO.getReportId());
    }

    /**
     * 获取评论信息
     *
     * @param reportId
     * @return
     */
    public List<UserReportCommentRespVO> getReportComment(Long reportId) {
        return reportCommentMapper.selectReportComment(reportId);
    }

    /*
        每天凌晨一点执行这个任务
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void userReportCheck() {
        log.info("开始检查用户日报汇报情况");
        // 获取昨天的日期
        LocalDate yesterday = LocalDate.now().minusDays(1);
        LocalDateTime startOfYesterday = yesterday.atStartOfDay();
        LocalDateTime endOfYesterday = yesterday.atTime(23, 59, 59);
        //非管理员/非离职
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .eq(User::getIsAdmin, 0)
                .eq(User::getEmpStatus, 0);
        List<User> userList = userMapper.selectList(wrapper);
        log.info("开始查询汇报模块扣分规则");
        LambdaQueryWrapper<ScoreLevel> wrapper1 = new LambdaQueryWrapper<ScoreLevel>().eq(ScoreLevel::getModule, 3);
        ScoreLevel scoreLevel = scoreLevelMapper.selectOne(wrapper1);
        if (scoreLevel == null) {
            throw new RuntimeException("找不到汇报模块扣分规则!");
        }
        for (User user : userList) {
            log.info("开始查询用户[{}]是否填写日报", user.getUserName());
            LambdaQueryWrapper<TReport> queryWrapper = new LambdaQueryWrapper<TReport>()
                    .eq(TReport::getUserId, user.getUserId())
                    .ge(TReport::getCreateDateTime, startOfYesterday).le(TReport::getCreateDateTime, endOfYesterday);
            Long count = tReportMapper.selectCount(queryWrapper);
            if (count > 0) {
                log.info("用户[{}]已经填写日报", user.getUserName());
                continue;
            }
            if (count == 0) {
                log.info("{}用户找不到昨天汇报日志,将按照扣分机制", user.getUserName());
                ScoreLog scoreLog = new ScoreLog();
                scoreLog.setUserId(user.getUserId());
                scoreLog.setBeforeScore(user.getScore());
                scoreLog.setSid(scoreLevel.getSid());
                scoreLog.setUpdateScore("-" + scoreLevel.getScore());
                scoreLog.setFid(0L);
                scoreLog.setAfterScore(user.getScore() - scoreLevel.getScore());
                scoreLog.setCreateDateTime(new Date());
                scoreLog.setFName("汇报模块");
                scoreLogMapper.insert(scoreLog);
                log.info("开始扣除User表数据,用户{}", user.getUserName());
                user.setScore(scoreLog.getAfterScore());
                userMapper.updateById(user);
                log.info("任务结束");
            }
        }
    }
}
